package com.ruoyi.web.controller.property.garbage;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.ApproveMission;
import com.ruoyi.common.core.domain.entity.GarbageRecord;
import com.ruoyi.common.core.domain.entity.GarbageRecordDetail;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.GarbageRecordDetailMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.system.service.ApproveService;
import com.ruoyi.system.service.GarbageRecordDetailService;
import com.ruoyi.system.service.GarbageRecordService;
import com.ruoyi.system.service.resp.GarbageRecordDTO;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author: ruohao
 * @Date: 2023/8/30
 **/
@RestController
@RequestMapping("/property/garbage/record")
public class RecordController extends BaseController {
    @Resource
    private GarbageRecordService garbageRecordService;

    @Resource
    private GarbageRecordDetailService garbageRecordDetailService;

    @Resource
    private ApproveService approveService;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysUserPostMapper sysUserPostMapper;

    @Resource
    private GarbageRecordDetailMapper garbageRecordDetailMapper;

    @Log(title = "获取垃圾记录", businessType = BusinessType.OTHER)
    @GetMapping("/list")
    public TableDataInfo list(GarbageRecord garbageRecord) {
//        Long userId = SecurityUtils.getUserId();
//        SysUser sysUser = sysUserMapper.selectUserById(userId);
//        List<Long> postIds = sysUserPostMapper.getUserPosts(SecurityUtils.getUserId());
//        if (CollectionUtils.isEmpty(postIds)) {
//            // 默认只能看到自己的数据
//            garbageRecord.setCreator(userId);
//            garbageRecord.setDept(null);
//        } else if (postIds.stream().anyMatch(p -> p < 7)) {
//            // 副主任以上能看到所有数据
//            garbageRecord.setCreator(null);
//            garbageRecord.setDept(null);
//        } else if (postIds.stream().anyMatch(p -> p <= 8 && p >= 7)) {
//            // 科长副科长只能看到自己科室的数据
//            garbageRecord.setCreator(null);
//            garbageRecord.setDept(sysUser.getDeptId());
//        } else {
//            // 其他人只能看到自己科室的自己的数据
//            garbageRecord.setCreator(userId);
//            garbageRecord.setDept(sysUser.getDeptId());
//        }
//        startPage();
        List<GarbageRecord> list = garbageRecordService.selectGarbageRecordList(garbageRecord);

        List<GarbageRecordDTO> res = fillToDTO(list);
        if (StringUtils.isBlank(garbageRecord.getApproveStatus()) || garbageRecord.getApproveStatus().equals("全部")) {

        } else {
            res = res.stream().filter(e -> e.getApproveStatus().equals(garbageRecord.getApproveStatus())).collect(Collectors.toList());
        }

        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        return myGetDataTable(res, pageNum, pageSize);
    }

    @GetMapping("/listAll")
    public TableDataInfo listAll() {
        List<GarbageRecord> list = garbageRecordService.selectAll();
        return getDataTable(list);
    }

    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable Long id) {
        return success(fillOneToDTO(garbageRecordService.selectGarbageRecordById(id)));
    }

    @GetMapping(value = "/approve/{id}")
    public AjaxResult approve(@PathVariable Long id) {
        return success(garbageRecordService.selectGarbageRecordById(id));
    }

    @Log(title = "新增垃圾记录", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public AjaxResult add(@Validated @RequestBody GarbageRecord garbageRecord) {
        Long userId = SecurityUtils.getUserId();
        garbageRecord.setCreator(userId);
        garbageRecord.setDept(Optional.ofNullable(sysUserMapper.selectUserById(userId)).map(SysUser::getDeptId).orElse(null));
        garbageRecord.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        Boolean result = garbageRecordService.createGarbageRecord(garbageRecord);
        if (result) {
            createDefaultDetail(garbageRecord.getId());
            return success();
        }
        return error();
    }

    private void createDefaultDetail(Long recordId) {
        GarbageRecordDetail detail = new GarbageRecordDetail();
        detail.setGarbageRecordId(recordId);
        detail.setGarbageTypeId(18L);
        detail.setLocation("二区");
        detail.setAmount(0L);
        detail.setUnit("斤");
        detail.setCreateBy(SecurityUtils.getNickName());
        GarbageRecordDetail detail1 = new GarbageRecordDetail();
        detail1.setGarbageRecordId(recordId);
        detail1.setGarbageTypeId(19L);
        detail1.setLocation("二区");
        detail1.setAmount(0L);
        detail1.setUnit("斤");
        detail1.setCreateBy(SecurityUtils.getNickName());
        GarbageRecordDetail detail2 = new GarbageRecordDetail();
        detail2.setGarbageRecordId(recordId);
        detail2.setGarbageTypeId(20L);
        detail2.setLocation("二区");
        detail2.setAmount(0L);
        detail2.setUnit("斤");
        detail2.setCreateBy(SecurityUtils.getNickName());
        GarbageRecordDetail detail3 = new GarbageRecordDetail();
        detail3.setGarbageRecordId(recordId);
        detail3.setGarbageTypeId(21L);
        detail3.setLocation("二区");
        detail3.setAmount(0L);
        detail3.setUnit("斤");
        detail3.setCreateBy(SecurityUtils.getNickName());
        GarbageRecordDetail detail4 = new GarbageRecordDetail();
        detail4.setGarbageRecordId(recordId);
        detail4.setGarbageTypeId(22L);
        detail4.setLocation("一区");
        detail4.setAmount(0L);
        detail4.setUnit("斤");
        detail4.setCreateBy(SecurityUtils.getNickName());
        GarbageRecordDetail detail5 = new GarbageRecordDetail();
        detail5.setGarbageRecordId(recordId);
        detail5.setGarbageTypeId(23L);
        detail5.setLocation("一区");
        detail5.setAmount(0L);
        detail5.setUnit("斤");
        detail5.setCreateBy(SecurityUtils.getNickName());
        GarbageRecordDetail detail6 = new GarbageRecordDetail();
        detail6.setGarbageRecordId(recordId);
        detail6.setGarbageTypeId(24L);
        detail6.setLocation("一区");
        detail6.setAmount(0L);
        detail6.setUnit("斤");
        detail6.setCreateBy(SecurityUtils.getNickName());
        GarbageRecordDetail detail7 = new GarbageRecordDetail();
        detail7.setGarbageRecordId(recordId);
        detail7.setGarbageTypeId(25L);
        detail7.setLocation("一区");
        detail7.setAmount(0L);
        detail7.setUnit("斤");
        detail7.setCreateBy(SecurityUtils.getNickName());
        garbageRecordDetailMapper.insert(detail);
        garbageRecordDetailMapper.insert(detail1);
        garbageRecordDetailMapper.insert(detail2);
        garbageRecordDetailMapper.insert(detail3);
        garbageRecordDetailMapper.insert(detail4);
        garbageRecordDetailMapper.insert(detail5);
        garbageRecordDetailMapper.insert(detail6);
        garbageRecordDetailMapper.insert(detail7);
    }

    @Log(title = "更新垃圾记录", businessType = BusinessType.UPDATE)
    @PutMapping
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult edit(@Validated @RequestBody GarbageRecord garbageRecord) {
        garbageRecord.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        Boolean result = garbageRecordService.updateGarbageRecord(garbageRecord);

        GarbageRecord search = garbageRecordService.selectGarbageRecordById(garbageRecord.getId());
        if (search == null || !search.getCreateBy().equals(SecurityUtils.getLoginUser().getUser().getNickName())) {
            throw new BaseException("该单据由" + search.getCreateBy() + "创建，您无法修改");
        }

        if (result) {
            return success();
        }
        return error();
    }

    @Log(title = "垃圾分类管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{id}")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult remove(@PathVariable Long id) {
        GarbageRecord search = garbageRecordService.selectGarbageRecordById(id);
        if (search == null || !search.getCreateBy().equals(SecurityUtils.getLoginUser().getUser().getNickName())) {
            throw new BaseException("该单据由" + search.getCreateBy() + "创建，您无法删除");
        }

        return toAjax(garbageRecordService.deleteGarbageRecordById(id));
    }

    private List<GarbageRecordDTO> fillToDTO(List<GarbageRecord> garbageRecords) {
        if (CollectionUtils.isEmpty(garbageRecords)) {
            return Collections.emptyList();
        }
        Page<GarbageRecordDTO> page = new Page<>();
        List<GarbageRecordDTO> garbageRecordDTOS = garbageRecords.stream().map(g -> {
            GarbageRecordDTO garbageRecordDTO = new GarbageRecordDTO();
            garbageRecordDTO.setId(g.getId());
            garbageRecordDTO.setRecorder(g.getRecorder());
            garbageRecordDTO.setRecordTime(g.getRecordTime());
            garbageRecordDTO.setExtra(g.getExtra());
            garbageRecordDTO.setCreateBy(g.getCreateBy());
            garbageRecordDTO.setCreateTime(g.getCreateTime());
            garbageRecordDTO.setUpdateBy(g.getUpdateBy());
            garbageRecordDTO.setUpdateTime(g.getUpdateTime());
            garbageRecordDTO.setRemark(g.getRemark());
            try {
                ApproveMission approveMission = approveService.getApproveMissionByActivityd(g.getId(), "垃圾记录详情审批");
                if (approveMission == null) {
                    garbageRecordDTO.setApproveStatus("未提交审批");
                } else if ("通过".equals(approveMission.getStatus()) || "拒绝".equals(approveMission.getStatus())) {
                    List<GarbageRecordDetail> garbageRecordDetails = garbageRecordDetailService.selectList(GarbageRecordDetail.builder().garbageRecordId(g.getId()).build());
                    Boolean editAfterApprove = false;
                    if (!CollectionUtils.isEmpty(garbageRecordDetails)) {
                        for (GarbageRecordDetail garbageRecordDetail : garbageRecordDetails) {
                            if (garbageRecordDetail.getCreateTime().compareTo(approveMission.getApproveTime()) > 0
                                    || (garbageRecordDetail.getUpdateTime() != null && garbageRecordDetail.getUpdateTime().compareTo(approveMission.getApproveTime()) > 0)) {
                                editAfterApprove = true;
                                break;
                            }
                        }
                    }
                    if (editAfterApprove) {
                        garbageRecordDTO.setApproveStatus("修改后未提交审批");
                    } else {
                        garbageRecordDTO.setApproveStatus(approveMission.getStatus());
                    }
                } else {
                    garbageRecordDTO.setApproveStatus(approveMission.getStatus());
                }
            } catch (Exception e) {
                logger.error("垃圾记录详情 获取审批状态失败", e);
            }
            return garbageRecordDTO;
        }).collect(Collectors.toList());
        page.addAll(garbageRecordDTOS);
        if (!CollectionUtils.isEmpty(garbageRecords)) {
            PageInfo<GarbageRecord> oldPage = new PageInfo<>(garbageRecords);
            page.setTotal(oldPage.getTotal());
        }
        return page;
    }

    private GarbageRecordDTO fillOneToDTO(GarbageRecord garbageRecord) {
        if (garbageRecord == null) {
            return null;
        }
        GarbageRecordDTO garbageRecordDTO = new GarbageRecordDTO();
        garbageRecordDTO.setRecorder(garbageRecord.getRecorder());
        garbageRecordDTO.setRecordTime(garbageRecord.getRecordTime());
        garbageRecordDTO.setExtra(garbageRecord.getExtra());
        garbageRecordDTO.setCreateBy(garbageRecord.getCreateBy());
        garbageRecordDTO.setCreateTime(garbageRecord.getCreateTime());
        garbageRecordDTO.setUpdateBy(garbageRecord.getUpdateBy());
        garbageRecordDTO.setUpdateTime(garbageRecord.getUpdateTime());
        garbageRecordDTO.setRemark(garbageRecord.getRemark());
        ApproveMission approveMission = approveService.getApproveMissionByActivityd(garbageRecord.getId(), "垃圾记录详情审批");
        garbageRecordDTO.setApproveStatus(Optional.ofNullable(approveMission).map(ApproveMission::getStatus).orElse("未提交审批"));
        return garbageRecordDTO;
    }
}
